/*
 *  OpenSlide, a library for reading whole slide image files
 *
 *  Copyright (c) 2007-2013 Carnegie Mellon University
 *  Copyright (c) 2011 Google, Inc.
 *  Copyright (c) 2022 Benjamin Gilbert
 *  All rights reserved.
 *
 *  OpenSlide is free software: you can redistribute it and/or modify
 *  it under the terms of the GNU Lesser General Public License as
 *  published by the Free Software Foundation, version 2.1.
 *
 *  OpenSlide is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
 *  GNU Lesser General Public License for more details.
 *
 *  You should have received a copy of the GNU Lesser General Public
 *  License along with OpenSlide. If not, see
 *  <http://www.gnu.org/licenses/>.
 *
 */

/*
 * Synthetic vendor driver to test library dependencies.
 *
 * quickhash is the hash of the names and compressed contents of all test
 * items.
 *
 */

#include <config.h>

#include "openslide-private.h"
#include "openslide-decode-bmp.h"
#include "openslide-decode-dicom.h"
#include "openslide-decode-jp2k.h"
#include "openslide-decode-jpeg.h"
#include "openslide-decode-png.h"
#include "openslide-decode-tiff.h"
#include "openslide-decode-tifflike.h"
#include "openslide-decode-xml.h"

#include <glib.h>
#include <string.h>
#include <stdlib.h>
#include <tiffio.h>

#define IMAGE_PIXELS 16
#define IMAGE_BUFSIZE (4 * IMAGE_PIXELS * IMAGE_PIXELS)

struct level {
  struct _openslide_level base;
  struct _openslide_grid *grid;
};

struct synthetic_item {
  const char *name;
  const char *description;
  bool is_valid;
  bool is_image;
  bool (*decode)(const void *data, uint32_t len, uint32_t *dest, GError **err);
  uint32_t uncompressed_size;
  uint32_t compressed_size;
  const uint8_t *compressed_data;
};

static const struct synthetic_item **synthetic_items;

static bool decode_bmp(const void *data, uint32_t len,
                       uint32_t *dest, GError **err) {
  return _openslide_bmp_decode_buffer(data, len, dest,
                                      IMAGE_PIXELS, IMAGE_PIXELS, err);
}

static bool decode_dicom(const void *data, uint32_t len,
                         uint32_t *dest, GError **err) {
  DcmError *dcm_error = NULL;

  // open file
  g_autoptr(DcmFilehandle) fh =
    dcm_filehandle_create_from_memory(&dcm_error, data, len);
  if (!fh) {
    _openslide_dicom_propagate_error(err, dcm_error);
    g_prefix_error(err, "Creating filehandle: ");
    return false;
  }

  // read File Meta Information and check the media storage SOP
  const DcmDataSet *meta = dcm_filehandle_get_file_meta(&dcm_error, fh);
  if (!meta) {
    _openslide_dicom_propagate_error(err, dcm_error);
    g_prefix_error(err, "Reading File Meta Information: ");
    return false;
  }
  DcmElement *element =
    dcm_dataset_get(&dcm_error, meta,
                    dcm_dict_tag_from_keyword("MediaStorageSOPClassUID"));
  if (!element) {
    _openslide_dicom_propagate_error(err, dcm_error);
    g_prefix_error(err, "Reading SOP: ");
    return false;
  }
  const char *sop;
  if (!dcm_element_get_value_string(&dcm_error, element, 0, &sop)) {
    _openslide_dicom_propagate_error(err, dcm_error);
    g_prefix_error(err, "Reading SOP value string: ");
    return false;
  }
  if (!g_str_equal(sop, "1.2.840.10008.5.1.4.1.1.7.4")) {
    g_set_error(err, OPENSLIDE_ERROR, OPENSLIDE_ERROR_FAILED,
                "Unexpected media storage SOP: %s", sop);
    return false;
  }

  // read frame
  g_autoptr(DcmFrame) frame =
    dcm_filehandle_read_frame(&dcm_error, fh, 1);
  if (!frame) {
    _openslide_dicom_propagate_error(err, dcm_error);
    g_prefix_error(err, "Reading frame: ");
    return false;
  }

  // decode frame
  uint16_t w = dcm_frame_get_columns(frame);
  uint16_t h = dcm_frame_get_rows(frame);
  if (w != IMAGE_PIXELS || h != IMAGE_PIXELS) {
    g_set_error(err, OPENSLIDE_ERROR, OPENSLIDE_ERROR_FAILED,
                "Image dimensions %ux%u != %ux%u",
                w, h, IMAGE_PIXELS, IMAGE_PIXELS);
    return false;
  }
  return _openslide_jpeg_decode_buffer(dcm_frame_get_value(frame),
                                       dcm_frame_get_length(frame),
                                       dest, w, h, err);
}

static bool decode_j2k(const void *data, uint32_t len,
                        uint32_t *dest, GError **err) {
  return _openslide_jp2k_decode_buffer(dest, IMAGE_PIXELS, IMAGE_PIXELS,
                                       data, len, OPENSLIDE_JP2K_RGB, err);
}

static bool decode_jpeg(const void *data, uint32_t len,
                        uint32_t *dest, GError **err) {
  return _openslide_jpeg_decode_buffer(data, len, dest,
                                       IMAGE_PIXELS, IMAGE_PIXELS, err);
}

static bool decode_png(const void *data, uint32_t len,
                       uint32_t *dest, GError **err) {
  return _openslide_png_decode_buffer(data, len, dest,
                                      IMAGE_PIXELS, IMAGE_PIXELS, err);
}

struct mem_tiff {
  const uint8_t *data;
  int64_t offset;
  int64_t size;
};

static tsize_t mem_tiff_read(thandle_t th, tdata_t buf, tsize_t size) {
  struct mem_tiff *mem = th;
  int64_t count = MIN(mem->size - mem->offset, size);
  memcpy(buf, mem->data + mem->offset, count);
  mem->offset += count;
  return count;
}

static tsize_t mem_tiff_write(thandle_t th G_GNUC_UNUSED,
                             tdata_t data G_GNUC_UNUSED,
                             tsize_t size G_GNUC_UNUSED) {
  // fail
  return 0;
}

static toff_t mem_tiff_seek(thandle_t th, toff_t offset, int whence) {
  struct mem_tiff *mem = th;
  mem->offset = _openslide_compute_seek(mem->offset, mem->size, offset, whence);
  return mem->offset;
}

static int mem_tiff_close(thandle_t th G_GNUC_UNUSED) {
  return 0;
}

static toff_t mem_tiff_size(thandle_t th) {
  struct mem_tiff *mem = th;

  return mem->size;
}

static bool decode_tiff(const void *data, uint32_t len,
                        uint32_t *dest, GError **err) {
  // there's no reason for OpenSlide as a whole to support reading entire
  // TIFFs from memory, but we need it
  struct mem_tiff mem = {
    .data = data,
    .offset = 0,
    .size = len,
  };
  // mode: m disables mmap to avoid sigbus and other mmap fragility
  g_autoptr(TIFF) tiff =
    TIFFClientOpen("tiff", "rm", &mem, mem_tiff_read,  // ci-allow
                   mem_tiff_write, mem_tiff_seek, mem_tiff_close,
                   mem_tiff_size, NULL, NULL);
  if (tiff == NULL) {
    g_set_error(err, OPENSLIDE_ERROR, OPENSLIDE_ERROR_FAILED,
                "Couldn't open TIFF");
    return false;
  }

  struct _openslide_tiff_level tiffl = {0};
  if (!_openslide_tiff_level_init(tiff, 0, NULL, &tiffl, err)) {
    return false;
  }
  if (tiffl.tile_w != IMAGE_PIXELS || tiffl.tile_h != IMAGE_PIXELS) {
    g_set_error(err, OPENSLIDE_ERROR, OPENSLIDE_ERROR_FAILED,
                "Dimensional mismatch reading TIFF tile: "
                "expected %dx%d, found %"PRId64"x%"PRId64,
                IMAGE_PIXELS, IMAGE_PIXELS, tiffl.tile_w, tiffl.tile_h);
    return false;
  }

  return _openslide_tiff_read_tile(&tiffl, tiff, dest, 0, 0, err);
}

static bool decode_xml(const void *data, uint32_t len,
                       uint32_t *dest, GError **err) {
  // NUL-terminate
  g_autofree char *str = g_strndup(data, len);
  g_autoptr(xmlDoc) doc = _openslide_xml_parse(str, err);
  if (doc == NULL) {
    return false;
  }
  memset(dest, 0, IMAGE_BUFSIZE);
  return true;
}

static bool decode_zstd(const void *data, uint32_t len,
                        uint32_t *dest, GError **err) {
  g_autofree uint32_t *buf =
    _openslide_zstd_decompress_buffer(data, len, IMAGE_BUFSIZE, err);
  if (!buf) {
    return false;
  }
  for (int i = 0; i < IMAGE_PIXELS * IMAGE_PIXELS; i++) {
    dest[i] = GUINT32_FROM_BE(buf[i]);
  }
  return true;
}

static void level_free(struct level *level) {
  _openslide_grid_destroy(level->grid);
  g_free(level);
}
typedef struct level level;
G_DEFINE_AUTOPTR_CLEANUP_FUNC(level, level_free)

static void destroy(openslide_t *osr) {
  level_free((struct level *) osr->levels[0]);
  g_free(osr->levels);
}

static bool decode_item(const struct synthetic_item *item,
                        uint32_t *dest, GError **err) {
  g_autofree void *uncompressed =
    _openslide_inflate_buffer(item->compressed_data, item->compressed_size,
                              item->uncompressed_size, err);
  if (uncompressed == NULL) {
    g_prefix_error(err, "Decompressing %s: ", item->name);
    return false;
  }
  bool ok = item->decode(uncompressed, item->uncompressed_size, dest, err);
  if (item->is_valid && !ok) {
    g_prefix_error(err, "Decoding %s: ", item->name);
    return false;
  } else if (!item->is_valid && ok) {
    g_set_error(err, OPENSLIDE_ERROR, OPENSLIDE_ERROR_FAILED,
                "Decoding %s: invalid item decoded successfully", item->name);
    return false;
  } else if (!item->is_valid) {
    g_clear_error(err);
  }
  if (item->is_valid && item->is_image) {
    // check that pixels from the centers of the R/G/B swatches are reasonably
    // close to pure colors
    uint32_t r = dest[17 * IMAGE_PIXELS / 4];
    uint32_t g = dest[19 * IMAGE_PIXELS / 4];
    uint32_t b = dest[49 * IMAGE_PIXELS / 4];
    bool ok = true;
    // these limits are uncomfortably loose, but some versions of the JPEG
    // decoder are evidently this bad
    const uint8_t HI = 0xb0;
    const uint8_t LO = 0x50;
    #define byte(v, n) ((v >> (8 * n)) & 0xff)
    ok = ok && byte(r, 3) == 0xff && byte(g, 3) == 0xff && byte(b, 3) == 0xff;
    ok = ok && byte(r, 2) > HI && byte(g, 1) > HI && byte(b, 0) > HI;
    ok = ok && byte(r, 1) < LO && byte(r, 0) < LO;
    ok = ok && byte(g, 2) < LO && byte(g, 0) < LO;
    ok = ok && byte(b, 2) < LO && byte(b, 1) < LO;
    #undef byte
    if (!ok) {
      g_set_error(err, OPENSLIDE_ERROR, OPENSLIDE_ERROR_FAILED,
                  "Invalid image samples for %s: red %x, green %x, blue %x",
                  item->name, r, g, b);
      return false;
    }
  }
  return true;
}

static bool read_tile(openslide_t *osr G_GNUC_UNUSED,
                      cairo_t *cr,
                      struct _openslide_level *level,
                      int64_t tile_col, int64_t tile_row,
                      void *tile,
                      void *arg G_GNUC_UNUSED,
                      GError **err) {
  const struct synthetic_item *item = tile;

  // cache
  g_autoptr(_openslide_cache_entry) cache_entry = NULL;
  uint32_t *tiledata = _openslide_cache_get(osr->cache,
                                            level, tile_col, tile_row,
                                            &cache_entry);
  if (!tiledata) {
    g_autofree uint32_t *buf = g_malloc(IMAGE_BUFSIZE);
    if (!decode_item(item, buf, err)) {
      return false;
    }

    // put it in the cache
    tiledata = g_steal_pointer(&buf);
    _openslide_cache_put(osr->cache, level, tile_col, tile_row,
                         tiledata, IMAGE_BUFSIZE, &cache_entry);
  }

  // draw it
  g_autoptr(cairo_surface_t) surface =
    cairo_image_surface_create_for_data((unsigned char *) tiledata,
                                        CAIRO_FORMAT_ARGB32,
                                        IMAGE_PIXELS, IMAGE_PIXELS,
                                        IMAGE_PIXELS * 4);
  cairo_set_source_surface(cr, surface, 0, 0);
  cairo_paint(cr);

  return true;
}

static bool paint_region(openslide_t *osr G_GNUC_UNUSED, cairo_t *cr,
                         int64_t x, int64_t y,
                         struct _openslide_level *level,
                         int32_t w, int32_t h,
                         GError **err) {
  struct level *l = (struct level *) level;
  return _openslide_grid_paint_region(l->grid, cr, NULL,
                                      x / l->base.downsample,
                                      y / l->base.downsample,
                                      level, w, h,
                                      err);
}

static const struct _openslide_ops synthetic_ops = {
  .paint_region = paint_region,
  .destroy = destroy,
};

static bool synthetic_detect(const char *filename,
                             struct _openslide_tifflike *tl G_GNUC_UNUSED,
                             GError **err) {
  // only accept hardcoded filename
  if (!g_str_equal(filename, "")) {
    g_set_error(err, OPENSLIDE_ERROR, OPENSLIDE_ERROR_FAILED,
                "Unrecognized filename");
    return false;
  }

  // require debug flag
  if (!_openslide_debug(OPENSLIDE_DEBUG_SYNTHETIC)) {
    g_set_error(err, OPENSLIDE_ERROR, OPENSLIDE_ERROR_FAILED,
                "synthetic debug flag is not set");
    return false;
  }

  return true;
}

static bool synthetic_open(openslide_t *osr,
                           const char *filename G_GNUC_UNUSED,
                           struct _openslide_tifflike *tl G_GNUC_UNUSED,
                           struct _openslide_hash *quickhash1,
                           GError **err) {
  g_autoptr(level) level = g_new0(struct level, 1);
  level->grid =
    _openslide_grid_create_tilemap(osr, IMAGE_PIXELS, IMAGE_PIXELS,
                                   read_tile, NULL);

  g_autofree uint32_t *tiledata = g_malloc(IMAGE_BUFSIZE);
  const struct synthetic_item *item;
  int i;
  int32_t count = 0;
  for (i = 0, item = synthetic_items[i];
       item->name != NULL;
       i++, item = synthetic_items[i]) {
    // confirm that all decoders work in open(), rather than requiring the
    // caller to call read_region()
    if (!decode_item(item, tiledata, err)) {
      return false;
    }

    const char *rendered =
      item->is_valid && item->is_image ? "" : " (not rendered)";
    g_hash_table_insert(osr->properties,
                        g_strdup_printf("synthetic.item.%s", item->name),
                        g_strdup_printf("%s%s", item->description, rendered));
    if (item->is_valid && item->is_image) {
      _openslide_grid_tilemap_add_tile(level->grid,
                                       count, 0,
                                       0.0, 0.0,
                                       IMAGE_PIXELS, IMAGE_PIXELS,
                                       (void *) item);
      g_hash_table_insert(osr->properties,
                          g_strdup_printf("synthetic.image[%d]", count),
                          g_strdup(item->name));
      count++;
    }
    _openslide_hash_string(quickhash1, item->name);
    _openslide_hash_data(quickhash1,
                         item->compressed_data, item->compressed_size);
  }

  level->base.w = count * IMAGE_PIXELS;
  level->base.h = IMAGE_PIXELS;
  level->base.tile_w = IMAGE_PIXELS;
  level->base.tile_h = IMAGE_PIXELS;

  g_assert(osr->data == NULL);
  g_assert(osr->levels == NULL);
  osr->levels = g_new(struct _openslide_level *, 1);
  osr->levels[0] = (struct _openslide_level *) g_steal_pointer(&level);
  osr->level_count = 1;
  osr->ops = &synthetic_ops;

  return true;
}

const struct _openslide_format _openslide_format_synthetic = {
  .name = "synthetic",
  .vendor = "synthetic",
  .detect = synthetic_detect,
  .open = synthetic_open,
};

static const struct synthetic_item **synthetic_items = (const struct synthetic_item *[]){
  &(const struct synthetic_item){
    .name = "bmp",
    .description = "BMP",
    .is_valid = true,
    .is_image = true,
    .decode = decode_bmp,
    .uncompressed_size = 822,
    .compressed_size = 54,
    .compressed_data = (const uint8_t[]){
       0x78, 0xda, 0x73, 0xf2, 0x35, 0x63, 0x66, 0x00, 0x03, 0x33, 0x20, 0xd6,
       0x00, 0x62, 0x01, 0x28, 0x66, 0x64, 0x90, 0x80, 0x48, 0x40, 0xe5, 0x91,
       0xc1, 0x7f, 0x5c, 0x08, 0x09, 0x74, 0x20, 0x81, 0xa1, 0xa2, 0x1e, 0x17,
       0x18, 0x6c, 0xea, 0x71, 0xea, 0xc0, 0x69, 0xd0, 0xa8, 0x7a, 0x6a, 0xaa,
       0x07, 0x00, 0x9c, 0x25, 0x0a, 0x02,
    }
  },
  &(const struct synthetic_item){
    .name = "dicom.jpeg",
    .description = "YCbCr JPEG DICOM",
    .is_valid = true,
    .is_image = true,
    .decode = decode_dicom,
    .uncompressed_size = 1214,
    .compressed_size = 593,
    .compressed_data = (const uint8_t[]){
       0x78, 0xda, 0xc5, 0x53, 0x3d, 0x6f, 0xd3, 0x50, 0x14, 0xbd, 0xcf, 0x1f,
       0xb1, 0x13, 0x3b, 0xc1, 0x4e, 0xec, 0x34, 0x03, 0x83, 0x83, 0x90, 0xf0,
       0xf4, 0x78, 0xcf, 0x76, 0x6c, 0x27, 0x03, 0x1f, 0x4d, 0x14, 0x11, 0x91,
       0x34, 0x55, 0x9d, 0x08, 0x31, 0x45, 0x15, 0x15, 0x23, 0xe2, 0x17, 0xc0,
       0x1f, 0x60, 0x60, 0x41, 0xea, 0xc2, 0xc4, 0x54, 0x7e, 0x03, 0x03, 0x03,
       0x03, 0x03, 0x42, 0x8c, 0x40, 0x05, 0x0a, 0x7f, 0x80, 0x85, 0x8a, 0x11,
       0x73, 0x9f, 0x95, 0x56, 0x34, 0x43, 0x2b, 0xc4, 0xc0, 0x95, 0xad, 0x73,
       0x7c, 0xdf, 0xbd, 0xc7, 0xc7, 0xef, 0x5d, 0x03, 0xfc, 0xdf, 0x18, 0x8c,
       0xfa, 0x13, 0x09, 0x71, 0x3e, 0x56, 0xe0, 0x3d, 0xa2, 0x04, 0x04, 0xa6,
       0x9b, 0x02, 0x31, 0x88, 0x84, 0x38, 0x1f, 0x5d, 0x04, 0x4e, 0x03, 0x9a,
       0x46, 0x8c, 0x72, 0xc6, 0x58, 0x4a, 0x3b, 0x94, 0xd3, 0x08, 0x6f, 0x4e,
       0x13, 0x1a, 0x61, 0x85, 0x8c, 0x35, 0xbd, 0xa2, 0x26, 0x48, 0x62, 0xca,
       0x68, 0x12, 0x84, 0x8c, 0x71, 0x46, 0xc3, 0xa2, 0x2e, 0x48, 0x43, 0xce,
       0x93, 0x28, 0x88, 0x22, 0x1a, 0x05, 0x21, 0x22, 0xe5, 0x71, 0xda, 0xe1,
       0x31, 0xc7, 0x32, 0xda, 0xed, 0xa6, 0x61, 0x22, 0x81, 0x85, 0x0a, 0xcd,
       0xb5, 0xb7, 0x88, 0xa7, 0x88, 0x76, 0x98, 0x04, 0xf5, 0x13, 0x0f, 0xeb,
       0xfa, 0xe2, 0x8e, 0x69, 0x82, 0x1e, 0x1a, 0x90, 0xdd, 0xb2, 0x60, 0x3a,
       0x1c, 0x8e, 0xb2, 0xc5, 0xa0, 0x3f, 0x99, 0xdd, 0x5e, 0x84, 0x71, 0xe2,
       0xe9, 0xd0, 0x3c, 0xd7, 0xbf, 0x0e, 0xad, 0x7f, 0xf4, 0xaf, 0x83, 0x07,
       0x83, 0x9b, 0x80, 0x4a, 0x0c, 0x66, 0x13, 0x81, 0xdb, 0xe8, 0x46, 0xe0,
       0x1e, 0xf4, 0x33, 0x05, 0xee, 0x64, 0x03, 0x74, 0xf2, 0x14, 0xb6, 0xb7,
       0x00, 0xbf, 0xd4, 0x5a, 0xa1, 0x07, 0xe3, 0xa9, 0x40, 0x56, 0xf4, 0x5a,
       0x70, 0x03, 0x6b, 0x01, 0xb3, 0xd5, 0x33, 0xdc, 0x04, 0xe7, 0xbb, 0x89,
       0x3d, 0xa8, 0x9d, 0xa1, 0x10, 0x9e, 0xaf, 0xd0, 0xf1, 0xd0, 0x8d, 0xf0,
       0xef, 0x81, 0x0d, 0xa3, 0xc2, 0x53, 0x63, 0x85, 0x5e, 0xe1, 0xd1, 0x17,
       0x53, 0x91, 0x89, 0x73, 0xf7, 0x41, 0xc1, 0x8c, 0x09, 0x77, 0x37, 0x77,
       0x16, 0xc3, 0xf9, 0x78, 0xbc, 0x88, 0x82, 0xc0, 0x87, 0x52, 0xb1, 0x2a,
       0xea, 0x74, 0xec, 0x93, 0x80, 0x7b, 0xbe, 0x38, 0xe1, 0x4c, 0x9c, 0xb3,
       0x8f, 0x9a, 0xc7, 0x0c, 0x88, 0x60, 0x3a, 0x32, 0x72, 0xc2, 0xa4, 0x82,
       0x69, 0xc8, 0x64, 0x72, 0xac, 0x42, 0xe4, 0x3e, 0xb2, 0xad, 0x29, 0xaa,
       0xb4, 0x05, 0x63, 0xdc, 0x87, 0x7a, 0x7b, 0x90, 0x95, 0x00, 0x27, 0x24,
       0x08, 0x12, 0x1f, 0x9c, 0xb6, 0x70, 0x31, 0xca, 0xa6, 0x0b, 0xce, 0xba,
       0x3c, 0x5d, 0x70, 0x6f, 0xf9, 0xd8, 0x2a, 0xe6, 0x38, 0xc7, 0xf8, 0x95,
       0xc3, 0x52, 0x59, 0xcd, 0xbb, 0xe0, 0xd7, 0x08, 0xe6, 0x3f, 0xe6, 0x87,
       0xd0, 0x07, 0x59, 0x92, 0xc4, 0x85, 0xa1, 0xe0, 0xa5, 0xea, 0xaa, 0xaa,
       0x28, 0x6a, 0x45, 0xd3, 0x4a, 0xba, 0x59, 0x31, 0x4d, 0xa3, 0x62, 0x18,
       0xd5, 0x5a, 0xdd, 0xaa, 0xd6, 0xec, 0x9a, 0x61, 0x58, 0x4d, 0xcb, 0x6e,
       0x38, 0xae, 0xeb, 0x9a, 0x17, 0x36, 0x5a, 0x4d, 0xa7, 0x55, 0x77, 0x5c,
       0x47, 0x88, 0x10, 0x19, 0x7b, 0x14, 0xb5, 0xac, 0xaa, 0x65, 0xa7, 0x6a,
       0x54, 0x9d, 0xbf, 0x8e, 0xfc, 0x35, 0xd8, 0xba, 0x98, 0x0c, 0x99, 0xd8,
       0x20, 0xd9, 0x44, 0xb6, 0x49, 0xfe, 0x06, 0x5c, 0xdc, 0x95, 0xd3, 0xff,
       0xaa, 0x5e, 0xc6, 0xb4, 0x67, 0xe1, 0x7e, 0x48, 0xda, 0x1f, 0xe9, 0x06,
       0xd8, 0xae, 0xa4, 0x95, 0xeb, 0x1b, 0x57, 0x86, 0xbb, 0x7b, 0x58, 0xd1,
       0x22, 0xb8, 0x77, 0xa7, 0x5a, 0xb5, 0x72, 0xa5, 0xa4, 0xe3, 0x8a, 0x63,
       0x93, 0xf5, 0xff, 0x3f, 0xff, 0x0c, 0xa6, 0x4c, 0xf0, 0xad, 0xb2, 0x0d,
       0xd7, 0xa1, 0xe7, 0xed, 0x1e, 0xec, 0xbf, 0xbd, 0xbc, 0x7f, 0xf4, 0x6a,
       0x76, 0xff, 0xfb, 0xce, 0xd7, 0x9f, 0xdf, 0x3a, 0x2f, 0x3e, 0x1c, 0x1e,
       0x5c, 0xbd, 0xf4, 0xa0, 0x47, 0x9e, 0x3c, 0x7a, 0xf9, 0xfc, 0xc7, 0xd1,
       0xbb, 0x67, 0xf7, 0x1e, 0xe6, 0x9f, 0x70, 0x17, 0xbf, 0x2c, 0x45, 0xf7,
       0x6f, 0xed, 0x55, 0xb3, 0x98,
    }
  },
  &(const struct synthetic_item){
    .name = "j2k",
    .description = "J2K",
    .is_valid = true,
    .is_image = true,
    .decode = decode_j2k,
    .uncompressed_size = 428,
    .compressed_size = 394,
    .compressed_data = (const uint8_t[]){
       0x78, 0xda, 0xfb, 0xef, 0xff, 0x3f, 0x90, 0x41, 0x9f, 0x01, 0x04, 0x04,
       0xa0, 0x18, 0x06, 0x50, 0xf9, 0xcc, 0xec, 0x8c, 0x8c, 0x10, 0xf4, 0x3f,
       0x88, 0x81, 0x07, 0x28, 0xc0, 0xc4, 0xc8, 0xc8, 0xc2, 0xc2, 0xc0, 0xf8,
       0x3f, 0x86, 0x81, 0xdd, 0xc1, 0xc1, 0xc3, 0x23, 0xe0, 0x7f, 0x0a, 0x83,
       0x2a, 0x03, 0xa3, 0x73, 0x51, 0x6a, 0x62, 0x49, 0x6a, 0x8a, 0x42, 0x52,
       0xa5, 0x82, 0x7f, 0x41, 0x6a, 0x9e, 0x57, 0x80, 0xab, 0xbb, 0x42, 0x59,
       0x6a, 0x51, 0x71, 0x66, 0x7e, 0x9e, 0x82, 0xa1, 0x9e, 0xa9, 0x9e, 0xe1,
       0xff, 0x09, 0x0c, 0x5c, 0x20, 0xf3, 0x18, 0x2d, 0x81, 0x7a, 0x83, 0x19,
       0x38, 0x19, 0x19, 0x20, 0xc6, 0xc4, 0x32, 0x70, 0x30, 0x42, 0xcc, 0x01,
       0x0a, 0x32, 0x21, 0x04, 0x99, 0x20, 0x82, 0x93, 0xef, 0x27, 0x3a, 0x84,
       0x26, 0xa6, 0xcf, 0xef, 0x0a, 0xdd, 0x1f, 0x72, 0xda, 0x80, 0xe9, 0x41,
       0x6b, 0x20, 0xaf, 0x96, 0xce, 0xe5, 0x67, 0xb1, 0x6b, 0x8f, 0x4c, 0xad,
       0xd8, 0xc8, 0xf4, 0xe8, 0xb9, 0xb9, 0x4c, 0xbd, 0x2a, 0x63, 0x94, 0x1a,
       0xfb, 0x9d, 0x83, 0x16, 0x35, 0xff, 0x0e, 0x4d, 0xd0, 0xfb, 0xf3, 0xa8,
       0xfa, 0x40, 0x4a, 0xac, 0xec, 0xd3, 0x6b, 0x76, 0x2b, 0xbe, 0x2e, 0xc9,
       0xed, 0x16, 0x5a, 0xd4, 0xbc, 0xa1, 0xe9, 0xe9, 0xbf, 0x07, 0xae, 0xf7,
       0x99, 0x12, 0x1f, 0x6a, 0xd4, 0xca, 0xd6, 0xe7, 0x75, 0x49, 0x69, 0x1b,
       0xaa, 0x2f, 0xeb, 0xfe, 0x77, 0x48, 0x80, 0x39, 0xa3, 0xeb, 0x91, 0xc4,
       0x0e, 0x0b, 0x87, 0x4d, 0x13, 0xde, 0x7b, 0xfc, 0xdb, 0x6a, 0x9f, 0x6d,
       0xaf, 0x73, 0x7b, 0xc1, 0x5d, 0xed, 0xc0, 0xd3, 0xdb, 0x66, 0x27, 0x04,
       0xbf, 0x30, 0x99, 0x65, 0xb8, 0xe0, 0xfc, 0x1e, 0x3b, 0xbb, 0xc4, 0x09,
       0x3f, 0x9b, 0x1b, 0x42, 0xcc, 0x05, 0x2a, 0x0c, 0x84, 0xbf, 0xc6, 0x9f,
       0xfc, 0x2a, 0xb1, 0x2a, 0xfa, 0xb0, 0x97, 0x3e, 0x53, 0xeb, 0x59, 0xb1,
       0xd7, 0x59, 0xe7, 0xfc, 0xe5, 0x33, 0x77, 0xeb, 0xcb, 0xcd, 0x7b, 0xb1,
       0x59, 0x2e, 0xe6, 0xfc, 0x1e, 0x31, 0xbb, 0x09, 0x0d, 0x4a, 0x52, 0xfc,
       0x1a, 0xf6, 0x0c, 0x57, 0x0e, 0x44, 0xdf, 0xf7, 0x98, 0xf9, 0x99, 0xb3,
       0x7f, 0x03, 0x8f, 0x8a, 0xe2, 0x25, 0xb6, 0x39, 0x8a, 0xa7, 0xf6, 0x4d,
       0x67, 0xae, 0xba, 0x2d, 0xf8, 0xf8, 0xfb, 0xa2, 0x9e, 0x30, 0x15, 0x1d,
       0xbf, 0x0f, 0x07, 0x62, 0x1e, 0x4c, 0xa8, 0x0c, 0x5a, 0xff, 0x87, 0x95,
       0xe1, 0x94, 0xc3, 0xe4, 0xcb, 0xd9, 0xa5, 0x02, 0x93, 0x2f, 0xdb, 0xff,
       0x61, 0x66, 0x98, 0x77, 0xce, 0xe5, 0xd9, 0x04, 0xd6, 0x7d, 0x0c, 0xfb,
       0x18, 0x1c, 0x12, 0xcf, 0xdb, 0x37, 0xfc, 0x49, 0xa8, 0x63, 0x68, 0x50,
       0x16, 0x7c, 0xf8, 0xff, 0x26, 0x00, 0xd1, 0x64, 0x9b, 0x04,
    }
  },
  &(const struct synthetic_item){
    .name = "jpeg",
    .description = "YCbCr JPEG",
    .is_valid = true,
    .is_image = true,
    .decode = decode_jpeg,
    .uncompressed_size = 735,
    .compressed_size = 553,
    .compressed_data = (const uint8_t[]){
       0x78, 0xda, 0xfb, 0x7f, 0xe3, 0xff, 0x03, 0x06, 0x01, 0x2f, 0x37, 0x4f,
       0x37, 0x06, 0x46, 0x46, 0x06, 0x06, 0x46, 0x20, 0x64, 0xf8, 0x7f, 0x9b,
       0xc1, 0x99, 0x81, 0x99, 0x89, 0x09, 0x84, 0x80, 0x80, 0x05, 0x88, 0x58,
       0x39, 0x58, 0x59, 0x59, 0x58, 0x58, 0xb9, 0xd8, 0xd9, 0xd9, 0x38, 0x78,
       0xb8, 0x78, 0x78, 0xb8, 0xb9, 0xb8, 0xb9, 0x79, 0xf9, 0x84, 0x04, 0x78,
       0xf9, 0x04, 0xf9, 0xb8, 0xb9, 0x05, 0xc4, 0x04, 0x04, 0x85, 0x45, 0x44,
       0x45, 0x45, 0x79, 0xf8, 0xc5, 0x25, 0xc4, 0x44, 0x24, 0x84, 0x44, 0x44,
       0x45, 0x40, 0x86, 0x30, 0x32, 0x03, 0xf5, 0xb0, 0xb0, 0x72, 0xb2, 0xb2,
       0x72, 0x8a, 0xf0, 0x72, 0xf3, 0x8a, 0x90, 0x0c, 0xfe, 0x1f, 0x60, 0x10,
       0xe4, 0x60, 0x10, 0x60, 0x10, 0x60, 0x66, 0x54, 0x62, 0x60, 0x12, 0x64,
       0x64, 0x16, 0x64, 0xfc, 0x7f, 0x84, 0x41, 0x1e, 0xe8, 0x4e, 0x56, 0x46,
       0x30, 0x60, 0x80, 0x02, 0x46, 0x26, 0xa0, 0x1b, 0xd9, 0xd8, 0x39, 0x38,
       0xb9, 0xb8, 0x81, 0x0a, 0xb6, 0x0a, 0x30, 0x30, 0x31, 0x32, 0x33, 0x33,
       0xb1, 0x30, 0x83, 0x5c, 0x0d, 0x94, 0xad, 0x05, 0xca, 0x33, 0xb0, 0x08,
       0xb2, 0x0a, 0x29, 0x1a, 0x3a, 0xb2, 0x09, 0x07, 0x26, 0xb2, 0x2b, 0x15,
       0x8a, 0x18, 0x35, 0x4e, 0x5c, 0xc8, 0xa1, 0xec, 0xb4, 0xf1, 0xa0, 0x68,
       0xd0, 0xc5, 0x0f, 0x2a, 0xc6, 0x49, 0x45, 0x4d, 0x9c, 0x5c, 0x62, 0xe2,
       0x12, 0x92, 0x52, 0xaa, 0x6a, 0xea, 0x1a, 0x9a, 0x5a, 0x26, 0xa6, 0x66,
       0xe6, 0x16, 0x96, 0x56, 0xce, 0x2e, 0xae, 0x6e, 0xee, 0x1e, 0x9e, 0x5e,
       0xc1, 0x21, 0xa1, 0x61, 0xe1, 0x11, 0x91, 0x51, 0xc9, 0x29, 0xa9, 0x69,
       0xe9, 0x19, 0x99, 0x59, 0xc5, 0x25, 0xa5, 0x65, 0xe5, 0x15, 0x95, 0x55,
       0xcd, 0x2d, 0xad, 0x6d, 0xed, 0x1d, 0x9d, 0x5d, 0x93, 0x26, 0x4f, 0x99,
       0x3a, 0x6d, 0xfa, 0x8c, 0x99, 0xb3, 0x16, 0x2d, 0x5e, 0xb2, 0x74, 0xd9,
       0xf2, 0x15, 0x2b, 0x57, 0x6d, 0xda, 0xbc, 0x65, 0xeb, 0xb6, 0xed, 0x3b,
       0x76, 0xee, 0x3a, 0x74, 0xf8, 0xc8, 0xd1, 0x63, 0xc7, 0x4f, 0x9c, 0x3c,
       0x75, 0xe9, 0xf2, 0x95, 0xab, 0xd7, 0xae, 0xdf, 0xb8, 0x79, 0xeb, 0xe1,
       0xa3, 0xc7, 0x4f, 0x9e, 0x3e, 0x7b, 0xfe, 0xe2, 0xe5, 0xab, 0x8f, 0x9f,
       0x3e, 0x7f, 0xf9, 0xfa, 0xed, 0xfb, 0x8f, 0x9f, 0xbf, 0x40, 0xfe, 0x62,
       0x64, 0x60, 0x66, 0x84, 0x01, 0xac, 0xfe, 0x12, 0x04, 0xfa, 0x8b, 0x89,
       0x85, 0x85, 0x99, 0x85, 0x1d, 0xe4, 0x2f, 0x46, 0xa6, 0x72, 0x90, 0x02,
       0x41, 0x16, 0x56, 0x45, 0x43, 0x36, 0x21, 0xc7, 0x40, 0xf6, 0xc4, 0x42,
       0x61, 0x25, 0xa3, 0x46, 0x0e, 0x11, 0xa7, 0x89, 0x0b, 0x37, 0x1e, 0xe4,
       0x54, 0x36, 0x0e, 0xfa, 0x20, 0x9a, 0x54, 0x74, 0x91, 0x4b, 0x4c, 0xc5,
       0xe4, 0xa1, 0xea, 0x47, 0x90, 0xd7, 0xc0, 0x3e, 0x23, 0xce, 0x63, 0x4d,
       0x64, 0xf9, 0x0c, 0xee, 0x31, 0x84, 0xbf, 0xee, 0x32, 0x00, 0x5d, 0xfa,
       0xff, 0x16, 0x03, 0x0f, 0x33, 0x23, 0x30, 0x0a, 0x99, 0x05, 0x19, 0xec,
       0x19, 0x7e, 0x5e, 0xda, 0x77, 0x6c, 0xfd, 0xe9, 0x53, 0x7f, 0x13, 0xff,
       0x33, 0x34, 0xad, 0xfc, 0xc3, 0xf2, 0x9f, 0xa1, 0xf5, 0xe1, 0x7f, 0x06,
       0xae, 0xc3, 0xff, 0xd4, 0xf7, 0xdf, 0xd8, 0x7f, 0xb3, 0xfe, 0xd6, 0xfc,
       0x4f, 0xcf, 0x9f, 0xff, 0xdc, 0x97, 0x7e, 0xd3, 0xfe, 0xe5, 0xa2, 0xc7,
       0x72, 0xf1, 0xfb, 0x8a, 0x6f, 0x8b, 0x54, 0xcc, 0x7c, 0x90, 0xfe, 0x6b,
       0xe7, 0x57, 0xfb, 0x1f, 0x41, 0xdf, 0xe6, 0x5d, 0xbe, 0x55, 0x7f, 0x7a,
       0x5d, 0x74, 0xd1, 0xa7, 0xfa, 0xcb, 0xd7, 0xab, 0xef, 0xc4, 0x19, 0x3c,
       0xab, 0xff, 0x28, 0x55, 0xb7, 0xf0, 0x5d, 0x6d, 0xf0, 0xab, 0x79, 0xd7,
       0xd7, 0x6f, 0x7d, 0xfe, 0x6d, 0xdf, 0xf9, 0x53, 0xf3, 0xf5, 0xf5, 0x37,
       0x7f, 0xde, 0xfb, 0x2b, 0x3a, 0xfe, 0xff, 0x4d, 0x00, 0x49, 0xf4, 0x05,
       0xaf,
    }
  },
  &(const struct synthetic_item){
    .name = "jpeg.bad",
    .description = "Corrupt JPEG",
    .is_valid = false,
    .is_image = true,
    .decode = decode_jpeg,
    .uncompressed_size = 518,
    .compressed_size = 208,
    .compressed_data = (const uint8_t[]){
       0x78, 0xda, 0x95, 0x8e, 0x3b, 0x0e, 0xc2, 0x30, 0x10, 0x44, 0x77, 0xfd,
       0x21, 0x4e, 0xec, 0x84, 0x75, 0xb0, 0x81, 0x96, 0x9e, 0x3b, 0xa4, 0x40,
       0x42, 0x82, 0x9a, 0xc3, 0x90, 0x34, 0x1c, 0x85, 0xbb, 0x20, 0x0e, 0xc1,
       0xa7, 0xe1, 0x26, 0xc6, 0x2e, 0x40, 0x02, 0x01, 0x11, 0xa3, 0x2d, 0x56,
       0xa3, 0x37, 0xbb, 0x13, 0x4e, 0xe1, 0x06, 0xb4, 0x5e, 0xae, 0x96, 0x80,
       0x51, 0x73, 0x9c, 0x03, 0x84, 0x2b, 0x2c, 0x80, 0x33, 0x96, 0x26, 0x4a,
       0xc4, 0x91, 0x4a, 0x4a, 0x21, 0x64, 0x91, 0x65, 0x03, 0x65, 0x0a, 0x63,
       0x74, 0xa1, 0x75, 0x59, 0xd5, 0x54, 0x56, 0xb6, 0xd2, 0x9a, 0xc6, 0x64,
       0x47, 0xce, 0x7b, 0x6f, 0x86, 0x93, 0xe9, 0xd8, 0x4d, 0x6b, 0xe7, 0x5d,
       0x3a, 0x82, 0x3c, 0x66, 0x84, 0xcc, 0xa5, 0xcc, 0x5d, 0xa9, 0x4b, 0xf7,
       0xb7, 0xc2, 0x01, 0xac, 0x02, 0x04, 0xe4, 0x68, 0x81, 0x59, 0xe4, 0x16,
       0xc3, 0x11, 0x5c, 0x74, 0x5e, 0xa5, 0x92, 0x8b, 0x0f, 0x77, 0xdb, 0x76,
       0x5d, 0x9b, 0x96, 0x70, 0x01, 0xc3, 0x11, 0x18, 0x71, 0x02, 0xc0, 0xcd,
       0x3e, 0x51, 0xf4, 0x9e, 0x4d, 0x94, 0x8a, 0x59, 0x94, 0x6c, 0x97, 0x00,
       0xfb, 0x19, 0xe0, 0x88, 0x0d, 0xfe, 0x02, 0xd8, 0x13, 0xf8, 0xfa, 0x62,
       0xd0, 0xb0, 0xdf, 0x00, 0x36, 0xb3, 0xdd, 0xa3, 0x34, 0xf0, 0xe8, 0xd3,
       0xbe, 0xa7, 0x12, 0xf5, 0x55, 0xa2, 0xbe, 0x8f, 0x11, 0x38, 0xdf, 0x01,
       0x7f, 0x2f, 0x44, 0xdc,
    }
  },
  &(const struct synthetic_item){
    .name = "jpeg.rgb",
    .description = "RGB JPEG",
    .is_valid = true,
    .is_image = true,
    .decode = decode_jpeg,
    .uncompressed_size = 489,
    .compressed_size = 493,
    .compressed_data = (const uint8_t[]){
       0x78, 0xda, 0xfb, 0x7f, 0xe3, 0xff, 0x3b, 0x06, 0x3e, 0xc7, 0x94, 0xfc,
       0xa4, 0x54, 0x86, 0x14, 0x06, 0x10, 0xf8, 0x7f, 0x9b, 0xc1, 0x99, 0x81,
       0x99, 0x89, 0x09, 0x84, 0x80, 0x80, 0x05, 0x88, 0x58, 0x39, 0x58, 0x59,
       0x59, 0x58, 0x58, 0xb9, 0xd8, 0xd9, 0xd9, 0x38, 0x78, 0xb8, 0x78, 0x78,
       0xb8, 0xb9, 0xb8, 0xb9, 0x79, 0xf9, 0x84, 0x04, 0x78, 0xf9, 0x04, 0xf9,
       0xb8, 0xb9, 0x05, 0xc4, 0x04, 0x04, 0x85, 0x45, 0x44, 0x45, 0x45, 0x79,
       0xf8, 0xc5, 0x25, 0xc4, 0x44, 0x24, 0x84, 0x44, 0x44, 0x45, 0xfe, 0x1f,
       0x60, 0x10, 0xe4, 0x60, 0x10, 0x60, 0x10, 0x60, 0x0e, 0x12, 0x64, 0x70,
       0x17, 0x64, 0x70, 0x12, 0x64, 0xf8, 0x7f, 0x84, 0x41, 0x9e, 0x81, 0x81,
       0x91, 0x95, 0x11, 0x0c, 0x18, 0xa0, 0x80, 0x91, 0x09, 0x68, 0x3c, 0x1b,
       0x3b, 0x07, 0x27, 0x17, 0x37, 0x50, 0xc1, 0x56, 0x01, 0x06, 0x26, 0x46,
       0x66, 0x66, 0x26, 0x16, 0x66, 0x90, 0x85, 0x40, 0xd9, 0x5a, 0xa0, 0x3c,
       0x03, 0x8b, 0x20, 0xab, 0x90, 0xa2, 0xa1, 0x23, 0x9b, 0x70, 0x60, 0x22,
       0xbb, 0x52, 0xa1, 0x88, 0x51, 0xe3, 0xc4, 0x85, 0x1c, 0xca, 0x4e, 0x1b,
       0x0f, 0x8a, 0x06, 0x5d, 0xfc, 0xa0, 0x62, 0x9c, 0x54, 0xd4, 0xc4, 0xc9,
       0x25, 0x26, 0x2e, 0x21, 0x29, 0xa5, 0xaa, 0xa6, 0xae, 0xa1, 0xa9, 0x65,
       0x62, 0x6a, 0x66, 0x6e, 0x61, 0x69, 0xe5, 0xec, 0xe2, 0xea, 0xe6, 0xee,
       0xe1, 0xe9, 0x15, 0x1c, 0x12, 0x1a, 0x16, 0x1e, 0x11, 0x19, 0x95, 0x9c,
       0x92, 0x9a, 0x96, 0x9e, 0x91, 0x99, 0x55, 0x5c, 0x52, 0x5a, 0x56, 0x5e,
       0x51, 0x59, 0xd5, 0xdc, 0xd2, 0xda, 0xd6, 0xde, 0xd1, 0xd9, 0x35, 0x69,
       0xf2, 0x94, 0xa9, 0xd3, 0xa6, 0xcf, 0x98, 0x39, 0x6b, 0xd1, 0xe2, 0x25,
       0x4b, 0x97, 0x2d, 0x5f, 0xb1, 0x72, 0xd5, 0xa6, 0xcd, 0x5b, 0xb6, 0x6e,
       0xdb, 0xbe, 0x63, 0xe7, 0xae, 0x43, 0x87, 0x8f, 0x1c, 0x3d, 0x76, 0xfc,
       0xc4, 0xc9, 0x53, 0x97, 0x2e, 0x5f, 0xb9, 0x7a, 0xed, 0xfa, 0x8d, 0x9b,
       0xb7, 0x1e, 0x3e, 0x7a, 0xfc, 0xe4, 0xe9, 0xb3, 0xe7, 0x2f, 0x5e, 0xbe,
       0xfa, 0xf8, 0xe9, 0xf3, 0x97, 0xaf, 0xdf, 0xbe, 0xff, 0xf8, 0xf9, 0xeb,
       0xff, 0x5d, 0x06, 0x16, 0x06, 0xa6, 0xff, 0xb7, 0x18, 0x78, 0x98, 0x83,
       0x18, 0xdc, 0x19, 0x9c, 0x18, 0x18, 0xec, 0x19, 0xfe, 0x06, 0xaf, 0x3f,
       0xb5, 0xea, 0xcf, 0xaa, 0xf5, 0x4f, 0xe3, 0xf6, 0xaf, 0xea, 0xd2, 0xfe,
       0x7f, 0x01, 0xc8, 0x3c, 0xb5, 0x0a, 0x28, 0x78, 0xeb, 0xfd, 0x0f, 0xad,
       0xf9, 0x07, 0xfc, 0x7f, 0xc4, 0xc9, 0x7f, 0x58, 0x63, 0xff, 0xa8, 0xfa,
       0x6f, 0xf7, 0xdf, 0xe9, 0x7f, 0x57, 0xfe, 0x67, 0xd0, 0xab, 0xab, 0x9f,
       0xfd, 0xac, 0x76, 0xf2, 0xbf, 0x59, 0x7a, 0x86, 0x4f, 0x7f, 0x3f, 0xb7,
       0xdd, 0x18, 0xbf, 0xf5, 0xfe, 0x87, 0x50, 0xfb, 0x86, 0xf9, 0x1f, 0xf6,
       0xd8, 0x3f, 0x8c, 0xa8, 0x3f, 0xf2, 0xfd, 0xb7, 0xf8, 0x6f, 0xfd, 0xdf,
       0xc1, 0xff, 0x62, 0xfe, 0xfc, 0x67, 0x30, 0x3f, 0xf3, 0x5b, 0xfd, 0xaf,
       0x49, 0x4c, 0xf2, 0xe9, 0xef, 0xe7, 0xaa, 0x93, 0xf6, 0xb1, 0xfe, 0x67,
       0x68, 0x5a, 0xf9, 0x87, 0xe5, 0x3f, 0x43, 0xeb, 0xc3, 0xff, 0x0c, 0x5c,
       0x87, 0xff, 0xa9, 0xef, 0xbf, 0xb1, 0xff, 0x66, 0xfd, 0xad, 0xf9, 0x9f,
       0x9e, 0x3f, 0xff, 0xb9, 0x2f, 0xfd, 0xa6, 0xfd, 0xcb, 0x45, 0x8f, 0xe5,
       0xe2, 0xf7, 0x15, 0xdf, 0x16, 0xfd, 0x7f, 0x13, 0x00, 0x37, 0x40, 0xc4,
       0x7e,
    }
  },
  &(const struct synthetic_item){
    .name = "png",
    .description = "RGB PNG",
    .is_valid = true,
    .is_image = true,
    .decode = decode_png,
    .uncompressed_size = 101,
    .compressed_size = 104,
    .compressed_data = (const uint8_t[]){
       0x78, 0xda, 0xeb, 0x0c, 0xf0, 0x73, 0xe7, 0xe5, 0x92, 0xe2, 0x62, 0x60,
       0x60, 0xe0, 0xf5, 0xf4, 0x70, 0x09, 0x02, 0xd2, 0x02, 0x20, 0xcc, 0xc1,
       0x04, 0x24, 0x27, 0x4c, 0xcc, 0x30, 0x03, 0x52, 0x3a, 0x9e, 0x2e, 0x8e,
       0x21, 0x1a, 0xe7, 0x93, 0xff, 0x9c, 0x6f, 0x90, 0x35, 0x78, 0x34, 0x21,
       0x21, 0x49, 0x41, 0xb0, 0x27, 0x4b, 0x81, 0xcd, 0xc0, 0xc8, 0x20, 0x81,
       0xff, 0xc3, 0x7f, 0x8f, 0x43, 0x3d, 0x3d, 0x3d, 0xce, 0xf7, 0xf8, 0xe7,
       0xce, 0x9d, 0xdb, 0x7c, 0x93, 0x9f, 0x61, 0xf9, 0x45, 0xce, 0xad, 0x85,
       0x97, 0x7c, 0x6b, 0x81, 0xfa, 0x18, 0x3c, 0x5d, 0xfd, 0x5c, 0xd6, 0x39,
       0x25, 0x34, 0x01, 0x00, 0x02, 0xed, 0x1e, 0xcd,
    }
  },
  &(const struct synthetic_item){
    .name = "png.bad",
    .description = "Corrupt PNG",
    .is_valid = false,
    .is_image = true,
    .decode = decode_png,
    .uncompressed_size = 67,
    .compressed_size = 66,
    .compressed_data = (const uint8_t[]){
       0x78, 0xda, 0xeb, 0x0c, 0xf0, 0x73, 0xe7, 0xe5, 0x92, 0xe2, 0x62, 0x60,
       0x60, 0xe0, 0xf5, 0xf4, 0x70, 0x09, 0x02, 0xd2, 0x8c, 0x20, 0xcc, 0x01,
       0x24, 0x18, 0xac, 0xea, 0x66, 0x87, 0x02, 0x29, 0x2e, 0xcf, 0x70, 0xc7,
       0x10, 0x0e, 0xd9, 0xe4, 0x1f, 0xfc, 0x0c, 0x8c, 0x8c, 0x8c, 0x0c, 0x66,
       0xf1, 0xe9, 0x0d, 0x20, 0x59, 0x4f, 0x57, 0x3f, 0x97, 0x75, 0x4e, 0x09,
       0x4d, 0x00, 0x54, 0x5d, 0x0b, 0xcf,
    }
  },
  &(const struct synthetic_item){
    .name = "tiff.jpeg",
    .description = "Tiled JPEG classic TIFF",
    .is_valid = true,
    .is_image = true,
    .decode = decode_tiff,
    .uncompressed_size = 992,
    .compressed_size = 643,
    .compressed_data = (const uint8_t[]){
       0x78, 0xda, 0xf3, 0xf4, 0xd4, 0x62, 0xa8, 0x60, 0x60, 0x60, 0xf8, 0x7f,
       0xe3, 0xff, 0x01, 0x06, 0x41, 0x0e, 0x06, 0x01, 0x06, 0x01, 0x66, 0x46,
       0x25, 0x06, 0x26, 0x41, 0x46, 0x66, 0x41, 0xc6, 0xff, 0xb7, 0x18, 0x78,
       0x98, 0x19, 0x81, 0x1c, 0x66, 0x41, 0x06, 0x7b, 0x86, 0x47, 0xaf, 0x2f,
       0xad, 0x3e, 0xb8, 0xfa, 0x45, 0x7c, 0x9f, 0x9d, 0xd8, 0x7f, 0x86, 0x96,
       0xe9, 0xbf, 0xd9, 0xff, 0x1a, 0xbf, 0xb9, 0x9f, 0xfe, 0xdb, 0xfd, 0xcf,
       0xa6, 0xfb, 0xbb, 0xcb, 0xa7, 0xbf, 0x33, 0xfc, 0x5e, 0x1f, 0x65, 0xd1,
       0xdd, 0x6c, 0xb7, 0xf4, 0xcd, 0x7f, 0x86, 0xfa, 0xb3, 0x67, 0xeb, 0x37,
       0xe7, 0xae, 0xfd, 0xfb, 0xfc, 0x8e, 0xc5, 0x7a, 0xc1, 0x7f, 0x9b, 0xab,
       0x65, 0x6d, 0xe7, 0x6f, 0x7e, 0xf6, 0xef, 0xeb, 0xcf, 0x9d, 0xf5, 0x87,
       0xb3, 0x8b, 0x7e, 0xbe, 0xab, 0xff, 0x7f, 0x53, 0x88, 0x81, 0x81, 0x91,
       0x99, 0x81, 0x11, 0x68, 0xb3, 0x00, 0x10, 0x33, 0x22, 0xb1, 0x99, 0x80,
       0x6c, 0x66, 0x20, 0x9d, 0x06, 0x14, 0x60, 0x86, 0x8a, 0xb3, 0x03, 0x31,
       0x1b, 0x94, 0xcd, 0x06, 0xc4, 0x42, 0x50, 0x36, 0x08, 0x8b, 0x42, 0xd9,
       0x20, 0x3d, 0x52, 0x8c, 0xac, 0x60, 0x76, 0x18, 0x90, 0x90, 0x86, 0xb2,
       0xe3, 0x80, 0x84, 0x0c, 0x92, 0x7a, 0x0d, 0x28, 0x9b, 0x09, 0x88, 0x9d,
       0x90, 0xec, 0x75, 0x46, 0x62, 0xbb, 0x30, 0xb2, 0x80, 0xd9, 0x1c, 0x40,
       0xec, 0x0a, 0x65, 0x17, 0x00, 0x71, 0x30, 0xd4, 0x6d, 0x39, 0x40, 0x81,
       0x68, 0x46, 0x76, 0x06, 0x3b, 0xa0, 0x21, 0x8b, 0x80, 0x6c, 0x11, 0x26,
       0x56, 0xb0, 0xbb, 0x8a, 0x40, 0x0a, 0x81, 0xc0, 0x03, 0x6a, 0x17, 0x8c,
       0xe6, 0x00, 0x43, 0x46, 0x30, 0x64, 0x80, 0x8a, 0xfd, 0x87, 0xd2, 0x0d,
       0x04, 0xf8, 0xc0, 0x98, 0xb9, 0xcd, 0xe0, 0xcc, 0xc0, 0xc1, 0xc6, 0xc6,
       0xce, 0xc6, 0xca, 0xc1, 0xce, 0xce, 0xce, 0xc9, 0xc9, 0xc1, 0xc5, 0x23,
       0xc2, 0xcb, 0xc3, 0xcd, 0xcd, 0x23, 0x29, 0x24, 0xcc, 0x2f, 0x22, 0x2b,
       0x25, 0x2f, 0x27, 0x2b, 0x25, 0x23, 0xa3, 0xa0, 0xa2, 0xa7, 0xae, 0xa0,
       0xa4, 0xa3, 0x2c, 0x23, 0xa3, 0x61, 0xae, 0xa9, 0x63, 0x60, 0x68, 0x62,
       0x62, 0x22, 0xaf, 0x6e, 0x69, 0x6b, 0x61, 0x64, 0xa3, 0x67, 0x6c, 0x62,
       0x04, 0x32, 0x84, 0x91, 0x93, 0x93, 0x93, 0x87, 0x9b, 0x47, 0x82, 0x97,
       0x57, 0xc2, 0x48, 0x51, 0x46, 0xd1, 0x88, 0x64, 0xf0, 0xff, 0x08, 0x83,
       0x3c, 0xd0, 0x55, 0xac, 0x8c, 0x60, 0xc0, 0x00, 0x05, 0x8c, 0x4c, 0xcc,
       0x2c, 0xac, 0x6c, 0xec, 0x1c, 0x9c, 0x5c, 0xdc, 0x40, 0x05, 0x5b, 0x05,
       0x40, 0x51, 0xc8, 0xcc, 0xc4, 0xc2, 0xcc, 0xca, 0xca, 0xc2, 0x02, 0x94,
       0xad, 0x05, 0xca, 0x33, 0xb0, 0x08, 0xb2, 0x0a, 0x29, 0x1a, 0x3a, 0xb2,
       0x09, 0x07, 0x26, 0xb2, 0x2b, 0x15, 0x8a, 0x18, 0x35, 0x4e, 0x5c, 0xc8,
       0xa1, 0xec, 0xb4, 0xf1, 0xa0, 0x68, 0xd0, 0xc5, 0x0f, 0x2a, 0xc6, 0x49,
       0x45, 0x4d, 0x9c, 0x5c, 0x62, 0xe2, 0x12, 0x92, 0x52, 0xaa, 0x6a, 0xea,
       0x1a, 0x9a, 0x5a, 0x26, 0xa6, 0x66, 0xe6, 0x16, 0x96, 0x56, 0xce, 0x2e,
       0xae, 0x6e, 0xee, 0x1e, 0x9e, 0x5e, 0xc1, 0x21, 0xa1, 0x61, 0xe1, 0x11,
       0x91, 0x51, 0xc9, 0x29, 0xa9, 0x69, 0xe9, 0x19, 0x99, 0x59, 0xc5, 0x25,
       0xa5, 0x65, 0xe5, 0x15, 0x95, 0x55, 0xcd, 0x2d, 0xad, 0x6d, 0xed, 0x1d,
       0x9d, 0x5d, 0x93, 0x26, 0x4f, 0x99, 0x3a, 0x6d, 0xfa, 0x8c, 0x99, 0xb3,
       0x16, 0x2d, 0x5e, 0xb2, 0x74, 0xd9, 0xf2, 0x15, 0x2b, 0x57, 0x6d, 0xda,
       0xbc, 0x65, 0xeb, 0xb6, 0xed, 0x3b, 0x76, 0xee, 0x3a, 0x74, 0xf8, 0xc8,
       0xd1, 0x63, 0xc7, 0x4f, 0x9c, 0x3c, 0x75, 0xe9, 0xf2, 0x95, 0xab, 0xd7,
       0xae, 0xdf, 0xb8, 0x79, 0xeb, 0xe1, 0xa3, 0xc7, 0x4f, 0x9e, 0x3e, 0x7b,
       0xfe, 0xe2, 0xe5, 0xab, 0x8f, 0x9f, 0x3e, 0x7f, 0xf9, 0xfa, 0xed, 0xfb,
       0x8f, 0x9f, 0xbf, 0x40, 0xfe, 0x62, 0x04, 0xa6, 0x36, 0x18, 0xc0, 0xea,
       0x2f, 0x41, 0xa0, 0xbf, 0x98, 0x58, 0x58, 0x98, 0x59, 0xd8, 0x41, 0xfe,
       0x62, 0x64, 0x2a, 0x07, 0x29, 0x10, 0x64, 0x61, 0x55, 0x34, 0x64, 0x13,
       0x72, 0x0c, 0x64, 0x4f, 0x2c, 0x14, 0x56, 0x32, 0x6a, 0xe4, 0x10, 0x71,
       0x9a, 0xb8, 0x70, 0xe3, 0x41, 0x4e, 0x65, 0xe3, 0xa0, 0x0f, 0xa2, 0x49,
       0x45, 0x17, 0xb9, 0xc4, 0x54, 0x4c, 0x1e, 0xaa, 0x7e, 0x04, 0x79, 0x0d,
       0xec, 0x33, 0xe2, 0x3c, 0xd6, 0x44, 0x96, 0xcf, 0xe0, 0x1e, 0x43, 0xf8,
       0xeb, 0x26, 0x00, 0xd7, 0x31, 0x07, 0x5d,
    }
  },
  &(const struct synthetic_item){
    .name = "tiff.jpeg.big",
    .description = "Tiled JPEG BigTIFF",
    .is_valid = true,
    .is_image = true,
    .decode = decode_tiff,
    .uncompressed_size = 1118,
    .compressed_size = 630,
    .compressed_data = (const uint8_t[]){
       0x78, 0xda, 0xf3, 0xf4, 0xd4, 0x66, 0xe0, 0x60, 0x60, 0x60, 0xa8, 0x60,
       0x80, 0x80, 0xff, 0x37, 0xfe, 0x1f, 0x60, 0x10, 0xe4, 0x60, 0x10, 0x60,
       0x10, 0x60, 0x66, 0x54, 0x62, 0x60, 0x12, 0x64, 0x64, 0x16, 0x64, 0xfc,
       0x7f, 0x8b, 0x81, 0x87, 0x99, 0x11, 0xc8, 0x61, 0x16, 0x64, 0xb0, 0x67,
       0x78, 0xcc, 0x78, 0x70, 0xbd, 0xe7, 0x7a, 0x0e, 0x95, 0x79, 0xcf, 0xf6,
       0x35, 0xfd, 0xb8, 0xfe, 0xb0, 0xf9, 0x91, 0xe2, 0xc2, 0xdc, 0x3d, 0xbf,
       0xf5, 0x27, 0x7e, 0xeb, 0x9b, 0x98, 0x7f, 0x77, 0xf7, 0xe9, 0xef, 0x12,
       0xbf, 0xf7, 0xaf, 0x95, 0x71, 0x3c, 0xf8, 0x9f, 0x21, 0xf8, 0x5b, 0xe6,
       0xb5, 0xfd, 0xa6, 0xbf, 0xca, 0xb6, 0xcf, 0x28, 0xf4, 0xad, 0xff, 0x3a,
       0xf9, 0x66, 0xe6, 0xc9, 0x93, 0xf5, 0xd6, 0xf7, 0xee, 0x4d, 0xbb, 0xf1,
       0xff, 0x26, 0x83, 0x10, 0xd4, 0x3e, 0x06, 0x46, 0x66, 0x06, 0x46, 0x28,
       0x53, 0x00, 0x26, 0x84, 0x45, 0x8c, 0x09, 0x28, 0xc6, 0x0c, 0x65, 0x73,
       0x80, 0x21, 0x03, 0x03, 0x33, 0x92, 0x3a, 0x76, 0x28, 0xcd, 0x86, 0x24,
       0xc6, 0x06, 0xa5, 0x85, 0x90, 0xc4, 0x60, 0xb4, 0x28, 0x92, 0x18, 0xcc,
       0x5c, 0x29, 0x46, 0x56, 0xb8, 0x98, 0x07, 0x54, 0xad, 0x34, 0x16, 0x31,
       0x19, 0x2c, 0xe6, 0x69, 0x20, 0x89, 0x31, 0x41, 0x69, 0x27, 0x2c, 0xfe,
       0x70, 0xc6, 0x22, 0xe6, 0xc2, 0x28, 0x80, 0x21, 0xe6, 0x8a, 0x24, 0x96,
       0x0e, 0xa5, 0x83, 0x91, 0xc2, 0x80, 0x11, 0x0c, 0x19, 0x18, 0xa2, 0x19,
       0xd9, 0x19, 0xec, 0xa0, 0x16, 0x2a, 0x40, 0x69, 0x11, 0x26, 0x56, 0xb8,
       0xdf, 0x3f, 0xc0, 0x0c, 0x41, 0x02, 0x20, 0xa1, 0xff, 0x50, 0xba, 0x81,
       0x00, 0x1f, 0x98, 0x1e, 0x6e, 0x33, 0x38, 0x33, 0x70, 0xb0, 0xb1, 0xb1,
       0xb3, 0xb1, 0x72, 0xb0, 0xb3, 0xb3, 0x73, 0x72, 0x72, 0x70, 0xf1, 0x88,
       0xf0, 0xf2, 0x70, 0x73, 0xf3, 0x48, 0x0a, 0x09, 0xf3, 0x8b, 0xc8, 0x4a,
       0xc9, 0xcb, 0xc9, 0x4a, 0xc9, 0xc8, 0x28, 0xa8, 0xe8, 0xa9, 0x2b, 0x28,
       0xe9, 0x28, 0xcb, 0xc8, 0x68, 0x98, 0x6b, 0xea, 0x18, 0x18, 0x9a, 0x98,
       0x98, 0xc8, 0xab, 0x5b, 0xda, 0x5a, 0x18, 0xd9, 0xe8, 0x19, 0x9b, 0x18,
       0x81, 0x0c, 0x61, 0xe4, 0xe4, 0xe4, 0xe4, 0xe1, 0xe6, 0x91, 0xe0, 0xe5,
       0x95, 0x30, 0x52, 0x94, 0x51, 0x34, 0x22, 0x19, 0xfc, 0x3f, 0xc2, 0x20,
       0x0f, 0x74, 0x15, 0x2b, 0x23, 0x18, 0xc0, 0x7d, 0xc3, 0xc4, 0xcc, 0xc2,
       0xca, 0xc6, 0xce, 0xc1, 0xc9, 0xc5, 0x0d, 0x54, 0xb0, 0x55, 0x00, 0x94,
       0x54, 0x98, 0x99, 0x58, 0x98, 0x59, 0x59, 0x59, 0x58, 0x80, 0xb2, 0xb5,
       0x40, 0x79, 0x06, 0x16, 0x41, 0x56, 0x21, 0x45, 0x43, 0x47, 0x36, 0xe1,
       0xc0, 0x44, 0x76, 0xa5, 0x42, 0x11, 0xa3, 0xc6, 0x89, 0x0b, 0x39, 0x94,
       0x9d, 0x36, 0x1e, 0x14, 0x0d, 0xba, 0xf8, 0x41, 0xc5, 0x38, 0xa9, 0xa8,
       0x89, 0x93, 0x4b, 0x4c, 0x5c, 0x42, 0x52, 0x4a, 0x55, 0x4d, 0x5d, 0x43,
       0x53, 0xcb, 0xc4, 0xd4, 0xcc, 0xdc, 0xc2, 0xd2, 0xca, 0xd9, 0xc5, 0xd5,
       0xcd, 0xdd, 0xc3, 0xd3, 0x2b, 0x38, 0x24, 0x34, 0x2c, 0x3c, 0x22, 0x32,
       0x2a, 0x39, 0x25, 0x35, 0x2d, 0x3d, 0x23, 0x33, 0xab, 0xb8, 0xa4, 0xb4,
       0xac, 0xbc, 0xa2, 0xb2, 0xaa, 0xb9, 0xa5, 0xb5, 0xad, 0xbd, 0xa3, 0xb3,
       0x6b, 0xd2, 0xe4, 0x29, 0x53, 0xa7, 0x4d, 0x9f, 0x31, 0x73, 0xd6, 0xa2,
       0xc5, 0x4b, 0x96, 0x2e, 0x5b, 0xbe, 0x62, 0xe5, 0xaa, 0x4d, 0x9b, 0xb7,
       0x6c, 0xdd, 0xb6, 0x7d, 0xc7, 0xce, 0x5d, 0x87, 0x0e, 0x1f, 0x39, 0x7a,
       0xec, 0xf8, 0x89, 0x93, 0xa7, 0x2e, 0x5d, 0xbe, 0x72, 0xf5, 0xda, 0xf5,
       0x1b, 0x37, 0x6f, 0x3d, 0x7c, 0xf4, 0xf8, 0xc9, 0xd3, 0x67, 0xcf, 0x5f,
       0xbc, 0x7c, 0xf5, 0xf1, 0xd3, 0xe7, 0x2f, 0x5f, 0xbf, 0x7d, 0xff, 0xf1,
       0xf3, 0x17, 0xc8, 0x5f, 0x8c, 0xc0, 0xd4, 0x0c, 0x03, 0x58, 0xfd, 0x25,
       0x08, 0xf4, 0x17, 0x13, 0x0b, 0x0b, 0x33, 0x0b, 0x3b, 0xc8, 0x5f, 0x8c,
       0x4c, 0xe5, 0x20, 0x05, 0x82, 0x2c, 0xac, 0x8a, 0x86, 0x6c, 0x42, 0x8e,
       0x81, 0xec, 0x89, 0x85, 0xc2, 0x4a, 0x46, 0x8d, 0x1c, 0x22, 0x4e, 0x13,
       0x17, 0x6e, 0x3c, 0xc8, 0xa9, 0x6c, 0x1c, 0xf4, 0x41, 0x34, 0xa9, 0xe8,
       0x22, 0x97, 0x98, 0x8a, 0xc9, 0x43, 0xd5, 0x8f, 0x20, 0xaf, 0x81, 0x7d,
       0x46, 0x9c, 0xc7, 0x9a, 0xc8, 0xf2, 0x19, 0xdc, 0x63, 0x08, 0x7f, 0xdd,
       0x04, 0x00, 0xcb, 0x8e, 0xff, 0x0d,
    }
  },
  &(const struct synthetic_item){
    .name = "tiff.lzw",
    .description = "Tiled LZW classic TIFF",
    .is_valid = true,
    .is_image = true,
    .decode = decode_tiff,
    .uncompressed_size = 411,
    .compressed_size = 271,
    .compressed_data = (const uint8_t[]){
       0x78, 0xda, 0xf3, 0xf4, 0xd4, 0x62, 0x68, 0x63, 0x60, 0x60, 0x68, 0xb0,
       0x3f, 0xc0, 0xc0, 0x21, 0xc2, 0xc7, 0xcb, 0xde, 0xe2, 0x94, 0xe8, 0x20,
       0xa1, 0xa3, 0x25, 0xcb, 0xdf, 0x7c, 0x30, 0x71, 0x23, 0xc7, 0x12, 0x39,
       0x49, 0xd1, 0x1e, 0x27, 0xa5, 0xc0, 0x19, 0x67, 0xe2, 0x2c, 0x25, 0x7b,
       0x8f, 0x3f, 0x9a, 0xf8, 0x52, 0x24, 0xc8, 0x59, 0xb5, 0xdd, 0x53, 0x55,
       0xe0, 0xa5, 0xcd, 0x3a, 0x41, 0xad, 0xe9, 0x6e, 0x0b, 0x0a, 0x2d, 0x7b,
       0xf8, 0x12, 0x4d, 0x67, 0x9e, 0x4b, 0x17, 0xc8, 0xdc, 0xf3, 0x8e, 0xd3,
       0x64, 0x6e, 0x83, 0x83, 0xe1, 0x29, 0x96, 0x4d, 0xdd, 0xa6, 0x0b, 0x03,
       0x55, 0x44, 0x2a, 0x7b, 0xd5, 0x1c, 0xbd, 0xe7, 0xbb, 0xae, 0x28, 0xf9,
       0x71, 0xf8, 0xdf, 0x4c, 0x8d, 0xd5, 0x6e, 0x81, 0xa6, 0xbb, 0x54, 0xe3,
       0xbc, 0x23, 0x7b, 0xc2, 0x2e, 0x9a, 0xde, 0xea, 0xf9, 0xb7, 0x35, 0x66,
       0x45, 0x48, 0x8e, 0x60, 0xb4, 0x48, 0x12, 0x13, 0x83, 0x30, 0x03, 0x03,
       0x23, 0x33, 0x03, 0x23, 0xd0, 0x1d, 0x02, 0x40, 0xcc, 0x88, 0xc4, 0x66,
       0x02, 0xb2, 0x59, 0x40, 0xee, 0x03, 0x0a, 0x30, 0x43, 0xc5, 0x59, 0x81,
       0x98, 0x0d, 0xca, 0x66, 0x02, 0x62, 0x21, 0x28, 0x1b, 0x84, 0x45, 0xa1,
       0x6c, 0x90, 0x1e, 0x29, 0x46, 0x56, 0x30, 0xbb, 0x00, 0x48, 0x48, 0x43,
       0xd9, 0x15, 0x40, 0x42, 0x06, 0x49, 0xbd, 0x2c, 0x23, 0x13, 0x03, 0x37,
       0x90, 0x9e, 0x00, 0xe4, 0x68, 0x20, 0x99, 0x69, 0x8b, 0xc4, 0x76, 0x42,
       0x72, 0x8f, 0x33, 0x12, 0xdb, 0x85, 0x91, 0x05, 0xcc, 0xe6, 0x00, 0x62,
       0x57, 0x28, 0xbb, 0x16, 0x88, 0x83, 0x90, 0xcc, 0x0f, 0x86, 0xba, 0xbf,
       0x03, 0xc4, 0x01, 0x02, 0x1d, 0x46, 0x88, 0x38, 0x8c, 0xe6, 0x80, 0x42,
       0x46, 0x28, 0x74, 0x4a, 0x4c, 0xce, 0x4e, 0x2f, 0xca, 0x2f, 0xcd, 0x4b,
       0x61, 0x00, 0x00, 0x90, 0xd7, 0x3d, 0x01,
    }
  },
  &(const struct synthetic_item){
    .name = "tiff.lzw.big",
    .description = "Tiled LZW BigTIFF",
    .is_valid = true,
    .is_image = true,
    .decode = decode_tiff,
    .uncompressed_size = 549,
    .compressed_size = 264,
    .compressed_data = (const uint8_t[]){
       0x78, 0xda, 0xf3, 0xf4, 0xd4, 0x66, 0xe0, 0x60, 0x60, 0x60, 0xe8, 0x63,
       0x80, 0x80, 0x06, 0xfb, 0x03, 0x0c, 0x1c, 0x22, 0x7c, 0xbc, 0xec, 0x2d,
       0x4e, 0x89, 0x0e, 0x12, 0x3a, 0x5a, 0xb2, 0xfc, 0xcd, 0x07, 0x13, 0x37,
       0x72, 0x2c, 0x91, 0x93, 0x14, 0xed, 0x71, 0x52, 0x0a, 0x9c, 0x71, 0x26,
       0xce, 0x52, 0xb2, 0xf7, 0xf8, 0xa3, 0x89, 0x2f, 0x45, 0x82, 0x9c, 0x55,
       0xdb, 0x3d, 0x55, 0x05, 0x5e, 0xda, 0xac, 0x13, 0xd4, 0x9a, 0xee, 0xb6,
       0xa0, 0xd0, 0xb2, 0x87, 0x2f, 0xd1, 0x74, 0xe6, 0xb9, 0x74, 0x81, 0xcc,
       0x3d, 0xef, 0x38, 0x4d, 0xe6, 0x36, 0x38, 0x18, 0x9e, 0x62, 0xd9, 0xd4,
       0x6d, 0xba, 0x30, 0x50, 0x45, 0xa4, 0xb2, 0x57, 0xcd, 0xd1, 0x7b, 0xbe,
       0xeb, 0x8a, 0x92, 0x1f, 0x87, 0xff, 0xcd, 0xd4, 0x58, 0xed, 0x16, 0x68,
       0xba, 0x4b, 0x35, 0xce, 0x3b, 0xb2, 0x27, 0xec, 0xa2, 0xe9, 0xad, 0x9e,
       0x7f, 0x5b, 0x63, 0x56, 0x84, 0xe4, 0x08, 0x46, 0x8b, 0x24, 0x31, 0x31,
       0x08, 0x43, 0x5d, 0xc1, 0xc0, 0xc8, 0xcc, 0xc0, 0x08, 0x65, 0x0a, 0xc0,
       0x84, 0xb0, 0x88, 0x31, 0x01, 0xc5, 0x58, 0xa0, 0x6c, 0x0e, 0x28, 0x64,
       0x46, 0x52, 0xc7, 0x0a, 0xa5, 0xd9, 0x90, 0xc4, 0x98, 0xa0, 0xb4, 0x10,
       0x92, 0x18, 0x8c, 0x16, 0x45, 0x12, 0x83, 0x99, 0x2b, 0xc5, 0xc8, 0x0a,
       0x17, 0xd3, 0x61, 0x84, 0xa8, 0x95, 0xc6, 0x22, 0x26, 0x83, 0xc5, 0x3c,
       0x59, 0x46, 0x26, 0x06, 0x6e, 0x98, 0x39, 0x50, 0x8b, 0x35, 0xb0, 0xb8,
       0xc5, 0x16, 0x8b, 0x98, 0x13, 0x16, 0xff, 0x3a, 0x63, 0x11, 0x73, 0x61,
       0x14, 0xc0, 0x10, 0x73, 0x45, 0x12, 0xab, 0x85, 0xd2, 0x41, 0x58, 0xdc,
       0x17, 0x8c, 0x14, 0x7e, 0x8c, 0x50, 0x08, 0x03, 0x4e, 0x89, 0xc9, 0xd9,
       0xe9, 0x45, 0xf9, 0xa5, 0x79, 0x29, 0x0c, 0x00, 0x7c, 0xc9, 0x3a, 0xc9,
    }
  },
  &(const struct synthetic_item){
    .name = "xml",
    .description = "XML document",
    .is_valid = true,
    .is_image = false,
    .decode = decode_xml,
    .uncompressed_size = 107,
    .compressed_size = 97,
    .compressed_data = (const uint8_t[]){
       0x78, 0xda, 0x0d, 0xcc, 0x41, 0x0e, 0x80, 0x20, 0x0c, 0x44, 0xd1, 0x3d,
       0xa7, 0x68, 0x7a, 0x00, 0xaa, 0x5b, 0x03, 0x78, 0x19, 0x1b, 0x25, 0xc1,
       0x96, 0x50, 0xa2, 0x1e, 0xdf, 0x6e, 0x66, 0x31, 0x3f, 0x79, 0x69, 0xff,
       0xee, 0x06, 0x0f, 0x0f, 0xab, 0x2a, 0x19, 0xd7, 0xb8, 0xe0, 0x5e, 0x42,
       0x9a, 0xda, 0xc1, 0x83, 0x58, 0xc6, 0x6b, 0xce, 0x6e, 0x1b, 0x91, 0x76,
       0x16, 0x6b, 0xf5, 0xe0, 0xa8, 0xe3, 0x24, 0x8f, 0x24, 0x2a, 0xe6, 0x1f,
       0x63, 0x09, 0x00, 0xa9, 0x8a, 0xf0, 0x00, 0x15, 0x76, 0x05, 0x61, 0xbe,
       0x9a, 0xd1, 0x07, 0xc9, 0x35, 0x72, 0xae, 0x84, 0x1f, 0x8c, 0xba, 0x22,
       0xce,
    }
  },
  &(const struct synthetic_item){
    .name = "zstd",
    .description = "Zstandard raw",
    .is_valid = true,
    .is_image = true,
    .decode = decode_zstd,
    .uncompressed_size = 50,
    .compressed_size = 61,
    .compressed_data = (const uint8_t[]){
       0x78, 0xda, 0x01, 0x32, 0x00, 0xcd, 0xff, 0x28, 0xb5, 0x2f, 0xfd, 0x64,
       0x00, 0x03, 0x25, 0x01, 0x00, 0x40, 0xff, 0xff, 0x00, 0x00, 0xff, 0x88,
       0x88, 0x88, 0x0a, 0xa0, 0x50, 0x2b, 0xf4, 0x10, 0x80, 0x1b, 0x1f, 0x3d,
       0x28, 0xcc, 0xd1, 0xec, 0x1d, 0xa2, 0x78, 0x39, 0xbb, 0xc4, 0xfb, 0x0e,
       0x54, 0x69, 0xec, 0xee, 0x24, 0x06, 0x73, 0xed, 0x77, 0xfb, 0x67, 0x15,
       0xcd,
    }
  },
  &(const struct synthetic_item){0}
};
